package com.example.countdown;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import java.io.IOException;
import java.util.ArrayList;

/**
 * create by sqs
 * 1037105071@qq.com
 */

public class MainService extends Service {

    private static final float BIG_WIDTH = 300;
    private static final float BIG_HEIGHT = 330;
    private static final float BIG_SHORT_WIDTH = 300;
    private static final float BIG_SHORT_HEIGHT = 260;
    private static final float MIN_WIDTH = 160;
    private static final float MIN_HEIGHH = 40;
    //计时器切换时间，剩余时间大于10秒的倒计时会5后进入切换
    private static final int TIMER_LIMATE = 10;

    private View mainview, smalliew;
    private WindowManager wm;
    private WindowManager.LayoutParams wmParm;
    private static MainActivity m;

    private MyCountDownView timeViewH, timeViewM, timeViewS;

    private ArrayList<String> gradeHour, gradeMin, gradeSec;
    private ImageView reset_but;
    private ImageButton startBut, allscreen_but;
    private Thread runable;
    //设置|大屏根布局
    private LinearLayout lin_show_big_time_content, lin_set_big_time_content;
    //大屏倒计时显示（00:00:00）
    private TextView show_hour_tv, show_min_tv, show_sec_tv;
    //小屏倒计时显示（00:00:00）
    private TextView small_hour_tv, small_min_tv, small_sec_tv;
    private Switch flicker_sw, voice_sw;
    //是否开始计时
    private boolean isHaveStart = false;
    //是否是暂停状态
    private boolean isPaused;
    //是否使用声音
    private boolean isUseVoice;
    private boolean isPlayingVoice;
    //是否使用震动动画
    private boolean isUserFlicker;
    private boolean isPlayingFlicker;

    private MediaPlayer myMediaPlayer;
    private ObjectAnimator objectAnimator;
    private TextView close;
    private View isShowingView;
    private LinearLayout flicker_root, voice_root;
    //倒计时剩余秒数
    private long supplusSecond;
    private View title;


    public static void saveActivity(Context context) {
        m = (MainActivity) context;
    }

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            TimePojo timePojo = (TimePojo) msg.obj;
            long hour = timePojo.getHour();
            long min = timePojo.getMin();
            long sec = timePojo.getSec();
            long sursec = timePojo.getSursec();
            String hourStr = hour + "";
            String minStr = min + "";
            String secStr = sec + "";
            supplusSecond = sursec;
            if (sec < 10)
                secStr = "0" + secStr;
            if (min < 10)
                minStr = "0" + minStr;
            if (hour < 10)
                hourStr = "0" + hourStr;
            show_hour_tv.setText(hourStr);
            show_min_tv.setText(minStr);
            show_sec_tv.setText(secStr);
            small_hour_tv.setText(hourStr);
            small_min_tv.setText(minStr);
            small_sec_tv.setText(secStr);

            try {
                if (isUseVoice && !isPlayingVoice && sec <= 5 && hour == 0 && min == 0) {
                    plyaMusic();
                }
                if (isUserFlicker && !isPlayingFlicker && sec <= 5 && hour == 0 && min == 0) {
                    plyaFlicker();

                }
                //如果倒计时结束
                if (hour == 0 && min == 0 && sec == 0) {
                    reset(true);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        wmParm = new WindowManager.LayoutParams();
        //如果大于android8.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            wmParm.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            wmParm.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
        wmParm.format = PixelFormat.RGBA_8888;
        wmParm.gravity = Gravity.CENTER;
        wmParm.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 焦点
        wmParm.width = DisplayUtils.dp2px(BIG_WIDTH);
        wmParm.height = DisplayUtils.dp2px(BIG_HEIGHT);
        super.onCreate();
    }

    private void initDate() {
        gradeHour = new ArrayList<>();
        gradeMin = new ArrayList<>();
        gradeSec = new ArrayList<>();
        for (int i = 0; i <= 24; i++)
            if (i < 10) {
                gradeHour.add("0" + i);
            } else {
                gradeHour.add(i + "");
            }

        for (int i = 0; i < 60; i++) {
            if (i < 10) {
                gradeMin.add("0" + i);
                gradeSec.add("0" + i);
            } else {
                gradeMin.add(i + "");
                gradeSec.add(i + "");
            }
        }
        timeViewH.setData(gradeHour, 0);
        timeViewM.setData(gradeMin, 0);
        timeViewS.setData(gradeSec, 30);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mainview = LayoutInflater.from(this).inflate(R.layout.mainview, null);
        smalliew = LayoutInflater.from(this).inflate(R.layout.smallview, null);
        title=mainview.findViewById(R.id.title);
        timeViewH = mainview.findViewById(R.id.hour);
        timeViewM = mainview.findViewById(R.id.min);
        timeViewS = mainview.findViewById(R.id.sec);
        startBut = mainview.findViewById(R.id.start_but);
        allscreen_but = mainview.findViewById(R.id.allscreen_but);
        reset_but = mainview.findViewById(R.id.rest_but);
        lin_show_big_time_content = mainview.findViewById(R.id.show_big_time_content);
        lin_set_big_time_content = mainview.findViewById(R.id.set_time_content);
        flicker_root = mainview.findViewById(R.id.flicker_root);
        voice_root = mainview.findViewById(R.id.voice_root);
        show_hour_tv = mainview.findViewById(R.id.hour_tv);
        show_min_tv = mainview.findViewById(R.id.min_tv);
        show_sec_tv = mainview.findViewById(R.id.sec_tv);
        flicker_sw = mainview.findViewById(R.id.flicker_sw);
        voice_sw = mainview.findViewById(R.id.voice_sw);
        close = mainview.findViewById(R.id.close);
        small_hour_tv = smalliew.findViewById(R.id.smalllH);
        small_min_tv = smalliew.findViewById(R.id.smalllM);
        small_sec_tv = smalliew.findViewById(R.id.smalllS);
        reset_but.setEnabled(true);
        startBut.setSelected(true);
        allscreen_but.setEnabled(false);

        initDate();
        setListener();
        wm.addView(mainview, wmParm);
        isShowingView = mainview;
        isShowingView.setTag(1);
        return super.onStartCommand(intent, flags, startId);
    }


    private final Object lock = new Object();

    private void startTime(String selectH, String selectM, String selectS) {
        int h = Integer.parseInt(selectH);
        int m = Integer.parseInt(selectM);
        int s = Integer.parseInt(selectS);
        supplusSecond = s + m * 60 + h * 60 * 60;
        runable = new Thread() {
            @Override
            public void run() {
                super.run();
                long time = s + m * 60 + h * 60 * 60;
                while (time > 0 && !isInterrupted()) {
                    time--;
                    try {
                        Thread.sleep(1000);
                        long hh = time / 60 / 60 % 60;
                        long mm = time / 60 % 60;
                        long ss = time % 60;
                        Message msg = new Message();
                        TimePojo timePojo = new TimePojo(hh, mm, ss, time);
                        msg.obj = timePojo;
                        if (isPaused) {
                            synchronized (lock) {
                                lock.wait();
                            }
                        }
                        handler.sendMessage(msg);

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Log.i("SQS", "是否终端+" + isInterrupted());
                        break;
                    }
                }
            }
        };
        runable.start();
    }

    /**
     * 继续时间
     */
    private void reStartTime() {
        synchronized (lock) {
            lock.notify();
        }
        isPaused = false;
        reStartDownTimer();
    }

    /**
     * 暂停时间
     */
    private void pauseTime() {
        isPaused = true;
        changeWindowSize(1);
        lin_set_big_time_content.setVisibility(View.GONE);
        lin_show_big_time_content.setVisibility(View.VISIBLE);
        stopMusic();
        stopFlicker();
    }


    private void setListener() {
        mainview.setOnTouchListener(new FloatingOnTouchListener());
        smalliew.setOnTouchListener(new FloatingOnTouchListener());
        startBut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isHaveStart) {
                    //第一次计时
                    String selectH = timeViewH.getSelectTime();
                    String selectM = timeViewM.getSelectTime();
                    String selectS = timeViewS.getSelectTime();
                    if ("00".equals(selectH) && "00".equals(selectM) && "00".equals(selectS)) {
                        Toast.makeText(GlobalApplication.context, "请选择正确时间", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    show_hour_tv.setText(selectH);
                    show_min_tv.setText(selectM);
                    show_sec_tv.setText(selectS);
                    startTime(selectH, selectM, selectS);
                    reStartDownTimer();
                    changeWindowSize(0);

                    isHaveStart = true;
                } else {
                    if (isPaused) {
                        //处于暂停状态,开始计时，显示部分布局
                        changeWindowSize(0);
                        reStartTime();
                    } else {
                        //处于计时状态，暂停，显示最大全布局
                        pauseTime();
                    }
                }

            }
        });
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopSelf();
                System.exit(0);
                wm.removeView(mainview);
            }
        });

        voice_sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isUseVoice = isChecked;
                if (isPlayingVoice && !isUseVoice) {
                    stopMusic();
                }
            }
        });

        flicker_sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isUserFlicker = isChecked;

            }
        });

        reset_but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                reset(false);
            }
        });


        allscreen_but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!v.isSelected()){
                    changeWindowSize(0);
                }else{
                    changeWindowSize(3);
                }

            }
        });

        smalliew.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //切换回大窗口显示
                changeWindowSize(0);
            }
        });

    }

    /**
     * 播放抖动动画
     */
    private void plyaFlicker() {
        startShakeByPropertyAnim(lin_show_big_time_content, 1, 1.2f, 3, 600);
    }

    /**
     * 播放音乐
     */
    public void plyaMusic() {

        AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int maxVolume = mAudioManager
                .getStreamMaxVolume(AudioManager.STREAM_MUSIC);// 获取最大声音
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0); // 设置为最大声音，可通过SeekBar更改音量大小
        AssetFileDescriptor fileDescriptor = null;
        try {
            if (myMediaPlayer == null) {
                AssetManager am = this.getAssets();
                fileDescriptor = am.openFd("14184.mp3");
                myMediaPlayer = new MediaPlayer();
                myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                myMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
                        fileDescriptor.getStartOffset(),
                        fileDescriptor.getLength());
                myMediaPlayer.prepare();
                myMediaPlayer.setLooping(true);
            }

            myMediaPlayer.start();
            isPlayingVoice = true;

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 暂停音乐
     */
    public void stopMusic() {
        isPlayingVoice = false;
        if (myMediaPlayer == null) return;
        myMediaPlayer.pause();
    }


    /**
     * 暂停抖动
     */
    private void stopFlicker() {
        isPlayingFlicker = false;
        if (objectAnimator != null) {
            objectAnimator.cancel();
        }
    }

    /**
     * 重置
     */
    private void reset(boolean isEnd) {
        //切换回大屏状态
        changeWindowSize(1);
        lin_set_big_time_content.setVisibility(View.VISIBLE);
        lin_show_big_time_content.setVisibility(View.GONE);
        stopMusic();
        stopFlicker();
        isHaveStart = false;
        isPaused = false;
        if (!isEnd && runable != null) {
            handler.removeCallbacksAndMessages(null);
            runable.interrupt();
        }
    }


    /**
     * 切换窗口尺寸
     *
     * @param type 0 大窗口（部分隐藏，不可设置时间） 1 大窗口(全显，可设置)  2 小窗口  3全屏
     */
    private void changeWindowSize(int type) {
        int tag = (int) isShowingView.getTag();
        float showingNormalTS = getResources().getDimension(R.dimen.showingNormalTimeTS);
        switch (type) {
            case 0:
                if (tag == 0) return;
                reStartDownTimer();
                startBut.setSelected(false);
                allscreen_but.setEnabled(true);
                allscreen_but.setSelected(true);
                reset_but.setEnabled(false);
                lin_set_big_time_content.setVisibility(View.GONE);
                lin_show_big_time_content.setVisibility(View.VISIBLE);
                flicker_root.setVisibility(View.GONE);
                voice_root.setVisibility(View.GONE);
                wmParm.width = DisplayUtils.dp2px(BIG_SHORT_WIDTH);
                wmParm.height = DisplayUtils.dp2px(BIG_SHORT_HEIGHT);
                show_hour_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                show_min_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                show_sec_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                if (tag == 2) {
                    wm.removeView(isShowingView);
                    wm.addView(mainview, wmParm);
                } else {
                    wm.updateViewLayout(mainview, wmParm);
                }
                isShowingView = mainview;
                isShowingView.setTag(0);

                break;
            case 1:
                if (tag == 1) return;
                startBut.setSelected(true);
                allscreen_but.setEnabled(false);
                reset_but.setEnabled(true);
                flicker_root.setVisibility(View.VISIBLE);
                voice_root.setVisibility(View.VISIBLE);
                wmParm.width = DisplayUtils.dp2px(BIG_WIDTH);
                wmParm.height = DisplayUtils.dp2px(BIG_HEIGHT);
                show_hour_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                show_min_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                show_sec_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingNormalTS);
                if (tag == 2) {
                    wm.removeView(isShowingView);
                    wm.addView(mainview, wmParm);
                } else if (tag == 0 || tag == 3) {
                    wm.updateViewLayout(mainview, wmParm);
                }
                isShowingView = mainview;
                isShowingView.setTag(1);
                downtimer.cancel();
                break;
            case 2:
                if (tag == 2) return;
                wm.removeView(isShowingView);
                wmParm.width = DisplayUtils.dp2px(MIN_WIDTH);
                wmParm.height = DisplayUtils.dp2px(MIN_HEIGHH);
                wm.addView(smalliew, wmParm);
                isShowingView = smalliew;
                isShowingView.setTag(2);
                break;

            case 3:
                downtimer.cancel();
                lin_set_big_time_content.setVisibility(View.GONE);
                lin_show_big_time_content.setVisibility(View.VISIBLE);
                wmParm.width = WindowManager.LayoutParams.MATCH_PARENT;
                wmParm.height = WindowManager.LayoutParams.MATCH_PARENT;
                //在java中从dimens文件取到的数值单位为px
                float showingAllTS = getResources().getDimension(R.dimen.showingAllTimeTS);
                show_hour_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingAllTS);
                show_min_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingAllTS);
                show_sec_tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, showingAllTS);
                allscreen_but.setSelected(false);
                wm.updateViewLayout(mainview, wmParm);
                isShowingView = mainview;
                isShowingView.setTag(3);
                break;
        }
    }

    /**
     * 倒计时
     */
    private CountDownTimer downtimer = new CountDownTimer(5000, 1000) {
        public void onTick(long millisUntilFinished) {
        }

        public void onFinish() {
            changeWindowSize(2);
        }
    };

    /**
     * 重置倒计时
     */
    private void reStartDownTimer() {
        if (downtimer != null) {
            downtimer.cancel();
            if (supplusSecond > 10) {
                downtimer.start();
            }

        }
    }


    /**
     * 抖动动画
     *
     * @param view
     * @param scaleSmall
     * @param scaleLarge
     * @param shakeDegrees
     * @param duration
     */
    private void startShakeByPropertyAnim(View view, float scaleSmall, float scaleLarge, float shakeDegrees, long duration) {
        if (view == null) {
            return;
        }
        //TODO 验证参数的有效性

        //先变小后变大
        PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_X,
                Keyframe.ofFloat(0f, 1.0f),
                Keyframe.ofFloat(0.25f, scaleSmall),
                Keyframe.ofFloat(0.5f, scaleLarge),
                Keyframe.ofFloat(0.75f, scaleLarge),
                Keyframe.ofFloat(1.0f, 1.0f)
        );
        PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder.ofKeyframe(View.SCALE_Y,
                Keyframe.ofFloat(0f, 1.0f),
                Keyframe.ofFloat(0.25f, scaleSmall),
                Keyframe.ofFloat(0.5f, scaleLarge),
                Keyframe.ofFloat(0.75f, scaleLarge),
                Keyframe.ofFloat(1.0f, 1.0f)
        );

        //先往左再往右
        PropertyValuesHolder rotateValuesHolder = PropertyValuesHolder.ofKeyframe(View.ROTATION,
                Keyframe.ofFloat(0f, 0f),
                Keyframe.ofFloat(0.1f, -shakeDegrees),
                Keyframe.ofFloat(0.2f, shakeDegrees),
                Keyframe.ofFloat(0.3f, -shakeDegrees),
                Keyframe.ofFloat(0.4f, shakeDegrees),
                Keyframe.ofFloat(0.5f, -shakeDegrees),
                Keyframe.ofFloat(0.6f, shakeDegrees),
                Keyframe.ofFloat(0.7f, -shakeDegrees),
                Keyframe.ofFloat(0.8f, shakeDegrees),
                Keyframe.ofFloat(0.9f, -shakeDegrees),
                Keyframe.ofFloat(1.0f, 0f)
        );

        objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, scaleXValuesHolder, scaleYValuesHolder, rotateValuesHolder);
        objectAnimator.setDuration(duration);
        objectAnimator.start();
        objectAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation, boolean isReverse) {
                isPlayingFlicker = true;
            }

            @Override
            public void onAnimationEnd(Animator animation, boolean isReverse) {
                isPlayingFlicker = false;
            }
        });
    }


    private class FloatingOnTouchListener implements View.OnTouchListener {
        private int x;
        private int y;

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();

                    break;
                case MotionEvent.ACTION_MOVE:
                    int nowX = (int) event.getRawX();
                    int nowY = (int) event.getRawY();
                    int movedX = nowX - x;
                    int movedY = nowY - y;
                    x = nowX;
                    y = nowY;
                    wmParm.x += movedX;
                    wmParm.y += movedY;
                    wm.updateViewLayout(view, wmParm);
                    break;
                default:

                    break;
            }
            return false;
        }
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (myMediaPlayer != null) {
            myMediaPlayer.release();
        }

    }
}
